
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-12-08     Wangjiangbo       the first version
 */

#include "app_comm.h"
#include "cJSON.h"
#include "app_io.h"
#include "app_nfc.h"

#define DBG_TAG "comm"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>


typedef struct {
    uint16_t cmd;
    uint8_t fan;

    struct {
        uint8_t style;
        uint8_t freq;
    } rgbs[2];

    char* nfc_string;
} json_req;

typedef struct {
    uint16_t cmd;

    uint8_t hall_trocar;            //戳卡
    uint8_t hall_arm;               //器械
    uint8_t hall_shell;             //无菌罩

    uint8_t key_drag;               //动力单元拖动
    uint8_t key_err_out;            //动力单元故障退出
    uint8_t key_drag_rcm_local;     //rcm臂位置拖动
    uint8_t key_drag_rcm_attitude;  //rcm臂姿态拖动

    uint8_t key_en;
    uint8_t key_up;
    uint8_t key_down;
    uint8_t key_left;
    uint8_t key_right;

    uint8_t sensor_top;
    uint8_t sensor_bottom;
    uint8_t sensor_left;
    uint8_t sensor_right;

    char* nfc_string;

} json_rep;


static bool _json_to_req(char* json_string, json_req* req)
{
    int len = strlen(json_string);

    if(len > 1024 || json_string == NULL)
        return false;

    cJSON *root = cJSON_Parse(json_string);
    cJSON *cmd = cJSON_GetObjectItem(root, "cmd");
    cJSON *fan = cJSON_GetObjectItem(root, "fan");
    cJSON *rgbs = cJSON_GetObjectItem(root, "rgbs");
    cJSON *nfc = cJSON_GetObjectItem(root, "nfc");//20230207

    req->cmd = cJSON_GetNumberValue(cmd);
    req->fan = cJSON_GetNumberValue(fan);

    for(int i = 0; i < 2; i++)
    {
        cJSON *d = cJSON_GetArrayItem(rgbs, i);
        cJSON *style = cJSON_GetObjectItem(d, "style");
        cJSON *freq = cJSON_GetObjectItem(d, "freq");

        req->rgbs[i].style = cJSON_GetNumberValue(style);
        req->rgbs[i].freq = cJSON_GetNumberValue(freq);
    }

    req->nfc_string = cJSON_GetStringValue(nfc);
//    /////
    LOG_D("json_req = \n%s", cJSON_Print(root));

    cJSON_Delete(root);
    return true;
}

static bool _req_to_jsong(json_rep* rep, char* json_string, int max_len)
{
    cJSON *cmd = cJSON_CreateNumber(rep->cmd);

    cJSON *arm = cJSON_CreateNumber(rep->hall_arm);
    cJSON *shell = cJSON_CreateNumber(rep->hall_shell);
    cJSON *trocar = cJSON_CreateNumber(rep->hall_trocar);

    cJSON *nfc = cJSON_CreateString(rep->nfc_string);


    cJSON *hall = cJSON_CreateObject();
    cJSON_AddItemToObject(hall, "arm", arm);
    cJSON_AddItemToObject(hall, "shell", shell);
    cJSON_AddItemToObject(hall, "trocar", trocar);

    cJSON *drag = cJSON_CreateNumber(rep->key_drag);
    cJSON *err_out = cJSON_CreateNumber(rep->key_err_out);
    cJSON *drag_rcm_local = cJSON_CreateNumber(rep->key_drag_rcm_local);
    cJSON *drag_rcm_attitude = cJSON_CreateNumber(rep->key_drag_rcm_attitude);
    cJSON *en = cJSON_CreateNumber(rep->key_en);
    cJSON *up = cJSON_CreateNumber(rep->key_up);
    cJSON *down = cJSON_CreateNumber(rep->key_down);
    cJSON *k_left = cJSON_CreateNumber(rep->key_left);
    cJSON *k_right = cJSON_CreateNumber(rep->key_right);

    cJSON *key = cJSON_CreateObject();
    cJSON_AddItemToObject(key, "drag", drag);
    cJSON_AddItemToObject(key, "err_out", err_out);
    cJSON_AddItemToObject(key, "drag_rcm_local", drag_rcm_local);
    cJSON_AddItemToObject(key, "drag_rcm_attitude", drag_rcm_attitude);
    cJSON_AddItemToObject(key, "en", en);
    cJSON_AddItemToObject(key, "up", up);
    cJSON_AddItemToObject(key, "down", down);
    cJSON_AddItemToObject(key, "left", k_left);
    cJSON_AddItemToObject(key, "right", k_right);

    cJSON *top = cJSON_CreateNumber(rep->sensor_top);
    cJSON *bottom = cJSON_CreateNumber(rep->sensor_bottom);
    cJSON *left = cJSON_CreateNumber(rep->sensor_left);
    cJSON *right = cJSON_CreateNumber(rep->sensor_right);

    cJSON *sensor = cJSON_CreateObject();
    cJSON_AddItemToObject(sensor, "top", top);
    cJSON_AddItemToObject(sensor, "bottom", bottom);
    cJSON_AddItemToObject(sensor, "left", left);
    cJSON_AddItemToObject(sensor, "right", right);

    cJSON *root = cJSON_CreateObject();
    cJSON_AddItemToObject(root, "cmd", cmd);
    cJSON_AddItemToObject(root, "hall", hall);
    cJSON_AddItemToObject(root, "key", key);
    cJSON_AddItemToObject(root, "sensor", sensor);
    cJSON_AddItemToObject(root, "nfc", nfc);////

    cJSON_PrintPreallocated(root, json_string, max_len, 1);

    char *str = cJSON_Print(root);
    LOG_D("json_rep = \n%s",str);

    free(str);
    cJSON_Delete(root);

    return true;
}


void app_comm_process(char* json_req_string, char* json_rep_buff, int json_rep_buff_max_len)
{
    json_req req = {0};
    json_rep rep = {0};

    _json_to_req(json_req_string, &req);

    gpio_map.fan_pow = req.fan;
    gpio_map.rgb[0].freq = req.rgbs[0].freq;
    gpio_map.rgb[0].style = req.rgbs[0].style;

    gpio_map.rgb[1].freq = req.rgbs[1].freq;
    gpio_map.rgb[1].style = req.rgbs[1].style;

    m_nfc._string=req.nfc_string;
//    rt_kprintf("rep.nfc=%s\n",m_nfc._string);

    rep.cmd = req.cmd + 0x8000;
    rep.hall_arm = gpio_map.hall_st[e_hall_arm];
    rep.hall_shell = gpio_map.hall_st[e_hall_shell];
    rep.hall_trocar = gpio_map.hall_st[e_hall_trocar];

    rep.key_drag = gpio_map.key_st[e_key_drag];
    rep.key_err_out = gpio_map.key_st[e_key_err_out];
    rep.key_drag_rcm_local = gpio_map.key_st[e_key_drag_rcm_local];
    rep.key_drag_rcm_attitude = gpio_map.key_st[e_key_drag_rcm_attitude];
    rep.key_en = gpio_map.key_st[e_key_en];
    rep.key_up = gpio_map.key_st[e_key_up];
    rep.key_down = gpio_map.key_st[e_key_down];
    rep.key_left = gpio_map.key_st[e_key_left];
    rep.key_right = gpio_map.key_st[e_key_right];

    rep.sensor_top = gpio_map.sense_st[e_sense_top];
    rep.sensor_bottom = gpio_map.sense_st[e_sense_bottom];
    rep.sensor_left = gpio_map.sense_st[e_sense_left];
    rep.sensor_right = gpio_map.sense_st[e_sense_right];

    rep.nfc_string=m_nfc._string;
//    rt_kprintf("rep.nfc=%s\n",rep.nfc_string);


    _req_to_jsong(&rep, json_rep_buff, json_rep_buff_max_len);
}



void Json_recv(char* json_req_string)
{
    json_req req = {0};

    _json_to_req(json_req_string, &req);

    gpio_map.fan_pow = req.fan;
    gpio_map.rgb[0].freq = req.rgbs[0].freq;
    gpio_map.rgb[0].style = req.rgbs[0].style;

    gpio_map.rgb[1].freq = req.rgbs[1].freq;
    gpio_map.rgb[1].style = req.rgbs[1].style;

    m_nfc._string=req.nfc_string;
//    rt_kprintf("rep.nfc=%s\n",m_nfc._string);
}

void Json_tx(char* json_rep_buff, int json_rep_buff_max_len)
{
    json_rep rep = {0};
    rep.cmd = 32769;
    rep.hall_arm = gpio_map.hall_st[e_hall_arm];
    rep.hall_shell = gpio_map.hall_st[e_hall_shell];
    rep.hall_trocar = gpio_map.hall_st[e_hall_trocar];

    rep.key_drag = gpio_map.key_st[e_key_drag];
    rep.key_err_out = gpio_map.key_st[e_key_err_out];
    rep.key_drag_rcm_local = gpio_map.key_st[e_key_drag_rcm_local];
    rep.key_drag_rcm_attitude = gpio_map.key_st[e_key_drag_rcm_attitude];
    rep.key_en = gpio_map.key_st[e_key_en];
    rep.key_up = gpio_map.key_st[e_key_up];
    rep.key_down = gpio_map.key_st[e_key_down];
    rep.key_left = gpio_map.key_st[e_key_left];
    rep.key_right = gpio_map.key_st[e_key_right];

    rep.sensor_top = gpio_map.sense_st[e_sense_top];
    rep.sensor_bottom = gpio_map.sense_st[e_sense_bottom];
    rep.sensor_left = gpio_map.sense_st[e_sense_left];
    rep.sensor_right = gpio_map.sense_st[e_sense_right];

    rep.nfc_string=m_nfc._string;
    rt_kprintf("rep.nfc=%s\n",rep.nfc_string);
    _req_to_jsong(&rep, json_rep_buff, json_rep_buff_max_len);
}

#if 0


[D/comm] json_req =
{
    "cmd":  1,                          //命令
    "fan":  1,                          //风扇
    "rgbs": [                           //rgb灯 一共两个
        {
            "style": 1,                 //0x4 红灯 0x2绿灯 0x1蓝灯  0x7 rgb全亮白等
            "freq": 2                   //闪烁评率 0 = 不闪 100 = 100hz闪烁
        },
        {
            "style": 3,
            "freq": 4
        }
    ]
}
[D/comm] json_rep =
{
    "cmd":  32769,                      //命令返回 1 | 0x8000
    "hall": {                           //霍尔传感器
        "arm":  0,                      //器械结合
        "shell": 0,                     //无菌罩结合
        "trocar": 0                     //戳卡结合
    },
    "key":  {
        "drag": 0,                      //动力盒 拖动按键
        "err_out":      0,              //动力盒 故障退出按键
        "drag_rcm_local": 0,            //RCM臂  位置拖动
        "drag_rcm_attitude":0,          //RCM臂  姿态拖动
        "en":   0,                      //RCM臂拖动备选方案 使用按键调整位置 使能
        "up":   0,                      //RCM臂拖动备选方案  上
        "down": 0,                      //RCM臂拖动备选方案  下
        "left": 0,                      //RCM臂拖动备选方案  左
        "right": 0                      //RCM臂拖动备选方案  右
    },
    "sensor":       {
        "top":  0,                      //RCM限位传感器 上
        "bottom": 0,                    //RCM限位传感器 下
        "left": 0,                      //RCM限位传感器 左
        "right": 0                      //RCM限位传感器 右
    }
}


#endif

